package com.css.fxfzypg.web.filter;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.constants.FxfzConstants;
import com.css.fxfzypg.util.PlatformHttpRequestUtils;
import com.css.fxfzypg.util.PlatformObjectUtils;
import com.css.fxfzypg.web.PlatformSessionContext;
import lombok.extern.slf4j.Slf4j;
import org.slw.common.helper.PropsHelper;
import org.slw.sso.client.SsoClient;
import org.slw.sso.config.SsoConfig;
import org.slw.sso.user.SsoUser;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class SessionFilter implements Filter {
    private static List<Pattern> patterns = new ArrayList<Pattern>();
    private FilterConfig filterConfig = null;
    Properties CONFIG_PROP = PropsHelper.loadProps("slw-config.properties");

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        String ignoreUrl = filterConfig.getInitParameter("ignoreUrl");
        log.debug("忽略路径为,ignoreUrl={}", ignoreUrl);
        if (!PlatformObjectUtils.isEmpty(ignoreUrl)) {
            String[] ignoreUrlArray = ignoreUrl.split(FxfzConstants.STR_SEPARATOR);
            for (String ignore : ignoreUrlArray) {
                Pattern pattern = Pattern.compile(ignore);
                patterns.add(pattern);
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        String ururl = request.getRequestURI();
        System.out.println(ururl);
        String url = request.getRequestURI().substring(request.getContextPath().length());
        log.debug("请求url={}", url);
        System.out.println(url);

        String charset = filterConfig.getInitParameter("charset");
        if (PlatformObjectUtils.isEmpty(charset)) {
            charset = FxfzConstants.DEFAULT_CHARSET;
        }
        request.setCharacterEncoding(charset);
        response.setCharacterEncoding(charset);
        String apptoken = request.getHeader("Authorization");
        if (isIgnore(url)) {
            log.debug("忽略路径,url={}", url);
            System.out.println("忽略路径,url="+ url);
            filterChain.doFilter(request, response);
        } else if (PlatformObjectUtils.isNotEmpty(apptoken)){
            filterChain.doFilter(request, response);
        }else {
            HttpSession session = request.getSession();

            if (!url.contains("local")) {
                //非游客登录，走单点
                // 从主站获取用户信息
                SsoUser ssoUser = SsoClient.getSsoUser(request, response);
                // 获取sso的session信息
                String sessionUserId = (String) session.getAttribute(FxfzConstants.CUR_USER_ID_IN_SESSION);

                // 主站有信息且子站有session才通過
                if (PlatformObjectUtils.isNotEmpty(ssoUser)) {
                    // 主站有登录
                    String ssoUserId = ssoUser.getUserId();

                    // 子站有登录
                    if (PlatformObjectUtils.isNotEmpty(sessionUserId)) {
                        String token = request.getHeader("token");
                        //判断请求头中是否带有签名
                        if (PlatformObjectUtils.isEmpty(token)) {
                            return;
                        }
                        if (!ssoUser.getUserId().equals(sessionUserId)) {
                            session.removeAttribute(FxfzConstants.CUR_USER_ID_IN_SESSION);
                            session.setAttribute(FxfzConstants.CUR_USER_ID_IN_SESSION, ssoUser.getUserId());
                            // ★★增加登录日志
                            log.debug("当前登录用户,userId={}", ssoUser.getUserId());
                            PlatformSessionContext.setUserID(ssoUser.getUserId());
                            String uri = request.getRequestURI();
                            filterChain.doFilter(request, response);
                            PlatformSessionContext.removeUserID();
                            System.out.println("dofilter---------------------");
                        } else {
                            log.debug("当前登录用户,userId={}", sessionUserId);
                            PlatformSessionContext.setUserID(sessionUserId);
                            String uri = request.getRequestURI();
                            filterChain.doFilter(request, response);
                            PlatformSessionContext.removeUserID();
                            System.out.println("dofilter---------------------");
                        }
                    } else {
                        // 子站未登录
                        // 写子站session
                        session.setAttribute(FxfzConstants.CUR_USER_ID_IN_SESSION, ssoUserId);
                        // ★★增加登录日志
                        log.debug("当前登录用户,userId={}", ssoUserId);
                        PlatformSessionContext.setUserID(ssoUserId);
                        filterChain.doFilter(request, response);
                        PlatformSessionContext.removeUserID();
                    }
                } else {
                    // 主站未登录
                    if (PlatformObjectUtils.isNotEmpty(sessionUserId)) {
                        // 子站有登录清除子站session
                        session.removeAttribute(FxfzConstants.CUR_USER_ID_IN_SESSION);
                    }

                    log.debug("跳转到登录页");
                    String requestParams = "";
                    if (PlatformObjectUtils.isNotEmpty(request.getParameterMap())) {
                        Map<String, String[]> requestParamsMap = request.getParameterMap();
                        Set<String> keySet = requestParamsMap.keySet();
                        for (String key : keySet) {
                            String paramValue = requestParamsMap.get(key)[0];
                            // 地址传递参数不应带中文
                            // paramValue = Base64.getEncoder().encodeToString(paramValue.getBytes(StandardCharsets.UTF_8));
                            if (PlatformObjectUtils.isEmpty(requestParams)) {
                                requestParams = "?" + key + "=" + paramValue;
                            } else {
                                requestParams += "_ssoParams_" + key + "=" + paramValue;
                            }
                        }
                    }
                    //登录后重定向到前端页面  首页
                    response.sendRedirect(SsoConfig.getInstance().getSsoServer() + SsoConfig.getInstance().getSsoCheckAciton() + CONFIG_PROP.getProperty("frontUrl"));
                }
            }else {
                //游客登录 不走单点
                String userId = (String) session.getAttribute(FxfzConstants.CUR_USER_ID_IN_SESSION);
                if (PlatformObjectUtils.isNotEmpty(userId)) {// userId 存在
                    log.debug("当前登录用户,userId={}", userId);
                    PlatformSessionContext.setUserID(userId);
                    filterChain.doFilter(request, response);
                    PlatformSessionContext.removeUserID();
                } else {
                    // userId不存在
                    session.invalidate();
                    if (PlatformHttpRequestUtils.isAjax(request)) {
                        log.debug("用户未登录,请求为ajax请求");
                        response.getWriter().write("{\"code\":\"401\"}");
                    } else {
                        log.debug("用户未登录,跳转到登录页");
                        request.getRequestDispatcher("/fxfzypg/login").forward(request, response);
                    }
                }
            }

        }
    }

    @Override
    public void destroy() {

    }
    private void retJson(Map<String, Object> map, HttpServletResponse response) throws IOException {
        JSONObject mapJson = new JSONObject(map);
        response.setHeader("Content-type", "text/html;chart=utf-8");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        out.write(mapJson.toJSONString());
    }
    /**
     * 是否需要过滤
     */
    private boolean isIgnore(String url) {
        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(url);
            if (matcher.matches()) {
                //如果匹配则是忽略路径
                return true;
            }
        }
        return false;
    }

}
